package com.lin.linchatgpt.service.email.impl;

import com.lin.linchatgpt.entity.User;
import com.lin.linchatgpt.entity.table.UserTableDef;
import com.lin.linchatgpt.exception.LinException;
import com.lin.linchatgpt.service.UserService;
import com.lin.linchatgpt.service.email.EmailService;
import com.lin.linchatgpt.utils.EmailTemplate;
import com.lin.linchatgpt.utils.ResultCode;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Copyright(C),2022年-2022,霖霖
 *
 * @author 霖霖
 * @version 1.0
 * @date 2023/6/10 13:40
 * @Description
 */
@Service
@Slf4j
public class EmailServiceImpl implements EmailService {
    @Resource
    private ThreadPoolExecutor taskExecutor;
    @Resource
    private JavaMailSender javaMailSender;

    @Value("${spring.mail.username}")
    private String from;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private UserService userService;

    @Value("${font.url}")
    private String fontUrl;

    @Async
    @Override
    public void sendEmail(String email) {

        taskExecutor.execute(()->{

            String subject = "验证码";
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);

            try {
                mimeMessageHelper.setSubject(subject);
                UUID uuid = UUID.randomUUID();
                // 将uuid存入redis中，并设置过期时间为20分钟
                redisTemplate.opsForValue().set(email, uuid.toString(), 60 * 20, TimeUnit.SECONDS);

                mimeMessageHelper.setText(EmailTemplate.getEmailContent(EmailTemplate.getValidLink(email, uuid.toString(), fontUrl)), true);
                mimeMessageHelper.setFrom(from);
                mimeMessageHelper.setTo(email);

                javaMailSender.send(mimeMessage);
            } catch (MessagingException e) {
                throw new LinException(ResultCode.ERROR, "邮件发送失败");
            } catch (MailSendException e) {
                throw new LinException(ResultCode.EMAIL_NOT_EXISTS, "邮箱地址不存在");
            }

        });
    }

    @Override
    public boolean verifyEmail(String email, String token) {
        // 1.从redis中取出token
        String redisToken = (String) redisTemplate.opsForValue().get(email);
        Optional.ofNullable(redisToken).orElseThrow(() -> new LinException(ResultCode.VALID_CODE_EXPIRED, "邮箱验证链接已过期，请重新获取"));
        // 2.比对
        if (token.equals(redisToken)) {
            // 3.如果相同，将redis中的token删除
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.where(UserTableDef.USER.EMAIL.eq(email));
            // 4.更新数据库中的邮箱验证状态
            User user = new User();
            user.setStatus(1);
            return userService.update(user, queryWrapper);
        }
        return false;
    }
}
